package xin.baizhiedu.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;
import xin.baizhiedu.Util.IPHostAddress;
import xin.baizhiedu.entity.AppFileLoad;
import xin.baizhiedu.mapper.AppFileUploadMapper;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Controller
@RequestMapping("/file")
public class FileController {

    private static final Logger log = LoggerFactory.getLogger(FileController.class);
    @Autowired
    AppFileUploadMapper appFileUploadMapper;
    @Value("${file.upload.dir}")
    private String realPath;

    /**
     * 文件上传
     * 注意：这种方式适用于任何一种部署方式 推荐使用这种方式
     *
     * @param file
     * @return
     * @throws IOException
     */
    @RequestMapping("/upload")
    @Transactional
    // 定义：接收文件对象 MultipartFile file变量名要与form表单中input type="file" 标签name属性名一致
    public String uploadByJarDeploy(Model model, ModelMap modelMap, MultipartFile file, @RequestParam("VERSIONNUMBER") String VERSIONNUMBER
            , @RequestParam("VERSIONNAME") String VERSIONNAME, @RequestParam("CONTENT") String CONTENT
            , @RequestParam("FORCEUPDATE") Boolean FORCEUPDATE, @RequestParam("STATE") String STATE
    ) throws IOException {

        // 文件名
        String originalFilename = file.getOriginalFilename();
        log.debug("文件名: {}", file.getOriginalFilename());
        log.debug("文件大小: {}", file.getSize());
        log.debug("文件类型: {}", file.getContentType());
        if (file.getSize() == 0) {
            model.addAttribute("res", "没有上传文件");
            return "upload";
        }
        // 改文件名
        String ext = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFileName = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS-").format(new Date()) + UUID.randomUUID() + ext;

        // 上传文件到哪
        if (CreateFile(realPath)) {
            file.transferTo(new File(realPath, newFileName));
        }
        QueryWrapper<AppFileLoad> wrapper = new QueryWrapper<>();
        List<AppFileLoad>  appFileLoadList=  appFileUploadMapper.selectList(wrapper);
        for (int i = 0; i < appFileLoadList.size(); i++) {
            AppFileLoad appFileLoad=new AppFileLoad();
            appFileLoad.setID(appFileLoadList.get(i).getID());
            appFileLoad.setSTATE("0");
            appFileUploadMapper.updateById(appFileLoad);
        }
        AppFileLoad appFileLoad = new AppFileLoad();
        appFileLoad.setCONTENT(CONTENT);
        appFileLoad.setSTATE(STATE);
        appFileLoad.setFORCEUPDATE(FORCEUPDATE);
        appFileLoad.setFILEURL(newFileName);
        appFileLoad.setVERSIONNAME(VERSIONNAME);
        appFileLoad.setVERSIONNUMBER(VERSIONNUMBER);
        appFileLoad.setTIME(IPHostAddress.time());
        appFileUploadMapper.insert(appFileLoad);
        QueryWrapper<AppFileLoad> wrappers = new QueryWrapper<>();
        wrappers.orderByDesc("VERSIONNUMBER");
        List<AppFileLoad>  appFileLoadLists=  appFileUploadMapper.selectList(wrappers);
        modelMap.put("appFileLoadList",appFileLoadLists);
        model.addAttribute("res", "文件上传成功");
        return "upload";
    }

    @GetMapping(value = "/getAppLoadInformation")
    @ResponseBody
    public List<AppFileLoad> gerUserInfo() {
        QueryWrapper<AppFileLoad> wrapper = new QueryWrapper<>();
        wrapper.eq("STATE", "1");
        return appFileUploadMapper.selectList(wrapper);
    }

    @GetMapping("/downloads")
    public ResponseEntity<Resource> downloadFile() throws Exception {
        QueryWrapper<AppFileLoad> wrapper = new QueryWrapper<>();
        wrapper.eq("STATE", "1");
        List<AppFileLoad>  appFileLoadList= appFileUploadMapper.selectList(wrapper);
        // 请求类型、请求参数、请求头 根据需求制定即可
        // 获取到需要下载的文件
        // 如何生成文件，根据实际业务需求改造即可
        String fileName = appFileLoadList.get(0).getFILEURL();
        String outputFilePath = realPath +"/"+fileName;
        log.debug("待下载文件:{}", outputFilePath);
        Path path = Paths.get(outputFilePath);
        Resource resource = null;
        try {
            resource = new UrlResource(path.toUri());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        // 设置请求头参数以及下载的文件名称,中文名称转义防止乱码
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+fileName+";filename*=UTF-8''" +
                UriUtils.encode(fileName, StandardCharsets.UTF_8));
        //
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("download-filename", fileName);
        // 返回响应实体，包含文件内容和响应头
        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(resource.contentLength())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(resource);
    }

    @GetMapping("/download")
    public ResponseEntity<Resource> downloadFile( @RequestParam("fileName") String fileName) throws Exception {
//        QueryWrapper<AppFileLoad> wrapper = new QueryWrapper<>();
//        wrapper.eq("STATE", "1");
//        List<AppFileLoad>  appFileLoadList= appFileUploadMapper.selectList(wrapper);
//        // 请求类型、请求参数、请求头 根据需求制定即可
//        // 获取到需要下载的文件
//        // 如何生成文件，根据实际业务需求改造即可
//        String fileName = appFileLoadList.get(0).getFILEURL();
        String outputFilePath = realPath +"/"+fileName;
        log.debug("待下载文件:{}", outputFilePath);
        Path path = Paths.get(outputFilePath);
        Resource resource = null;
        try {
            resource = new UrlResource(path.toUri());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        // 设置请求头参数以及下载的文件名称,中文名称转义防止乱码
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+fileName+";filename*=UTF-8''" +
                UriUtils.encode(fileName, StandardCharsets.UTF_8));
        //
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("download-filename", fileName);
        // 返回响应实体，包含文件内容和响应头
        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(resource.contentLength())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(resource);
    }


    /**
     * 判断是否有文件夹
     *
     * @param directoryPath
     * @return
     */
    public boolean CreateFile(String directoryPath) {
        File directory = new File(directoryPath);
        if (!directory.exists()) {
            boolean created = directory.mkdirs();
            if (created) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }


}
